home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / graphics / mandel18.2 < prev    next >
Internet Message Format  |  1989-05-18  |  54KB

  1. Path: xanth!ames!amdahl!oliveb!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i143:  mandel - mandelobrot generator v180, Part02/04
  5. Message-ID: <105554@sun.Eng.Sun.COM>
  6. Date: 17 May 89 15:53:24 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2046
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: u211344@hnykun11.bitnet (Olaf 'Rhialto' Seibert)
  12. Posting-number: Volume 89, Issue 143
  13. Archive-name: graphics/mandel180.2
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    GotMenu.c
  24. #    Jiff.c
  25. # This is archive 2 of a 4-part kit.
  26. # This archive created: Wed May 17 20:45:12 1989
  27. echo "extracting GotMenu.c"
  28. sed 's/^X//' << \SHAR_EOF > GotMenu.c
  29. X/*
  30. X * M A N D E L B R O T     C O N S T R U C T I O N   S E T
  31. X *
  32. X * (C) Copyright 1989 by Olaf Seibert.
  33. X * Mandel may be freely distributed. See file 'doc/Notice' for details.
  34. X *
  35. X * GotMenu and some (many) related things.
  36. X */
  37. X
  38. X#include <exec/types.h>
  39. X#include <intuition/intuition.h>
  40. X#include "mandel.h"
  41. X#ifdef DEBUG
  42. X#   include <stdio.h>
  43. X#   undef STATIC
  44. X#   define STATIC   /* EMPTY */
  45. X#endif
  46. X
  47. Xextern double ReMouse, ImMouse;
  48. Xextern UBYTE IPlotNr, EPlotNr;
  49. Xextern void UpdateDrwCm();
  50. X
  51. XTEXT FileName[FNAME_SIZE+1] = "Mandel.pic";
  52. XTEXT DirName[DNAME_SIZE+2]  = "";
  53. XUBYTE Buffer[5][20];
  54. X
  55. Xint (*DepthFuncArray[])() = {
  56. X    ZQuadMinC, ZC1MinZ, Z3PlusZCMin1MinC, UserProgFunc, I_ZQuadMinC
  57. X};
  58. X
  59. Xvoid (*IPlotFuncArray[])() = {
  60. X    None, PlotZ
  61. X};
  62. X
  63. Xvoid (*EPlotFuncArray[])() = {
  64. X    PlotIterationCount, PlotZ,
  65. X};
  66. X
  67. X/* Forward declarations of static procedures */
  68. XSTATIC void PrjNew();
  69. X
  70. Xvoid GotMenu(Code)
  71. XUSHORT Code;
  72. X{
  73. X    static void (*MenuFunc[])()= {
  74. X    CprMenu, PrjMenu, OptMenu, DrwMenu, BatchMenu
  75. X    };
  76. X    while (Code != MENUNULL) {
  77. X    (*MenuFunc[MENUNUM(Code)]) (Code);
  78. X    Code = ItemAddress(MandelMenu, (long) Code)->NextSelect;
  79. X    }
  80. X}
  81. X
  82. Xvoid CprMenu(Code)
  83. XUSHORT Code;
  84. X{
  85. X    extern long Revision;    /* From IncRev */
  86. X    ULONG OldIDCMP = MainWindow->IDCMPFlags;
  87. X
  88. X#define DATE            "16 April 1989 V1.3 ("
  89. X#define strlen_DATE        20
  90. X
  91. X    static UBYTE DateVersion[strlen_DATE+9] = DATE;
  92. X
  93. X    static struct IntuiText Body[] =
  94. X    {
  95. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  96. X        10, 15, NULL, (UBYTE *)"Mandelbrot Construction Set", &Body[1] },
  97. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  98. X        10, 30, NULL, (UBYTE *)"By KosmoSoft Productions", &Body[2] },
  99. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  100. X        10, 40, NULL, DateVersion, &Body[3] },
  101. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  102. X        10, 55, NULL, (UBYTE *)"Ohh, please Copy-Me!", NULL }
  103. X    },
  104. X    ExitText =
  105. X    {    MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  106. X    AUTOLEFTEDGE, AUTOTOPEDGE, NULL, (UBYTE *)" OK ", NULL };
  107. X
  108. X    sprintf(&DateVersion[strlen_DATE], "%ld)", Revision);
  109. X
  110. X    ModifyIDCMP(MainWindow, OldIDCMP &~ (MENUVERIFY | SIZEVERIFY | REQVERIFY));
  111. X    AutoRequest(MainWindow, &Body[0], NULL, &ExitText, NULL, NULL, 258L, 100L);
  112. X    ModifyIDCMP(MainWindow, OldIDCMP);
  113. X}
  114. X
  115. Xchar *CatFileComponents(dest, dirname, filename)
  116. Xchar *dest;
  117. Xchar *dirname;
  118. Xchar *filename;
  119. X{
  120. X    strcpy(dest, dirname);
  121. X    if (dirname[0] && dirname[strlen(dirname) - 1] != ':')
  122. X    strcat(dest, "/");
  123. X    strcat(dest, FileName);
  124. X
  125. X    return dest;
  126. X}
  127. X
  128. X
  129. Xbool OpenAs(name)
  130. Xchar *name;
  131. X{
  132. X    struct Mand MandChunk;
  133. X    struct ILBM_info *ilbminfo, *win_read_iff();
  134. X
  135. X    StopDrawing();
  136. X    MandChunk.MandID = 0;
  137. X    if (ilbminfo = win_read_iff(name, (short)FALSE,
  138. X    MainWindow, sizeof(MandChunk), &MandChunk)) {
  139. X    put_ea_cmap(&ilbminfo->cmap, NumColors, MandelScreen);
  140. X    InterpretMAND(&MandChunk, ilbminfo);
  141. X    }
  142. X    Saved = TRUE;
  143. X    NameValid = FALSE;
  144. X
  145. X    return ilbminfo != NULL;
  146. X}
  147. X
  148. Xbool SaveAs(name)
  149. Xchar *name;
  150. X{
  151. X    struct Mand MandChunk;
  152. X    unsigned char ea_colormap[3*MAXCOL];
  153. X
  154. X    get_ea_cmap(ea_colormap, NumColors, MandelScreen);
  155. X    MakeMAND(&MandChunk);
  156. X    SuspendDrawing();
  157. X    NameValid = Saved = write_iff(name, ea_colormap, MainWindow,
  158. X        (short) 0, (short) 0, (short) TRUE, sizeof(MandChunk),
  159. X        &MandChunk);
  160. X    ResumeDrawing();
  161. X
  162. X    return Saved;
  163. X}
  164. X
  165. XSTATIC void PrjMenu(Code)
  166. XUSHORT Code;
  167. X{
  168. X    int SubNum = SUBNUM(Code);
  169. X    int ItemNum = ITEMNUM(Code);
  170. X
  171. X    struct Mand MandChunk;
  172. X    char Name[DNAME_SIZE + FNAME_SIZE + 3];
  173. X
  174. X    switch (ItemNum) {
  175. X    case PRJNEW:
  176. X    PrjNew(SubNum);
  177. X    break;
  178. X    case PRJOPN:
  179. X    if ( get_fname(MainWindow, "Select a filename to OPEN",
  180. X        FileName, DirName) == NULL )
  181. X        break;
  182. X    CatFileComponents(Name, DirName, FileName);
  183. X    OpenAs(Name);
  184. X    break;
  185. X    case PRJSVE:    /* Save */
  186. X    if (NameValid) skipto prjsve;
  187. X    /* Fall Through */
  188. X    case PRJSVA:    /* Save As */
  189. X    if ( get_fname(MainWindow, "Select a filename to SAVE",
  190. X        FileName, DirName) == NULL )
  191. X        break;
  192. Xprjsve:
  193. X    CatFileComponents(Name, DirName, FileName);
  194. X    SaveAs(Name);
  195. X    break;
  196. X    case PRJSTP:
  197. X    StopDrawing();
  198. X    break;
  199. X    case PRJQUI:
  200. X    finished = TRUE;
  201. X    }
  202. X}
  203. X
  204. XSTATIC void OptMenu(Code)
  205. XUSHORT Code;
  206. X{
  207. X    int SubNum = SUBNUM(Code);
  208. X    int ItemNum = ITEMNUM(Code);
  209. X
  210. X    switch (ItemNum) {
  211. X    case OPTCOL:
  212. X    switch (SubNum) {
  213. X    case OCSEL:
  214. X        PenTableMode = SELECT;
  215. X        Select();
  216. X        break;
  217. X    case OCMOD:
  218. X        PenTableMode = MODULO;
  219. X        break;
  220. X    case OCRAN:
  221. X        PenTableMode = RANGES;
  222. X        break;
  223. X    case OCPAL:
  224. X        OpenColorWindow(MainWindow);
  225. X    } /* End Switch SUBNUM */
  226. X    InitPenTable();
  227. X    break;
  228. X    case OPTRES:
  229. X    switch (SubNum) {
  230. X    case ORNRM:
  231. X        PixelStep = 1;
  232. X        break;
  233. X    case OR12:
  234. X        PixelStep = 2;
  235. X        break;
  236. X    case OR13:
  237. X        PixelStep = 3;
  238. X        break;
  239. X    case OR14:
  240. X        PixelStep = 4;
  241. X        break;
  242. X    case ORFIL: /* Fill in */
  243. X        DrawPicture((bool)TRUE);
  244. X        break;
  245. X    case ORHI:
  246. X    case ORILC:
  247. X    case OREHB:
  248. X        {
  249. X        USHORT newmode = MandelNScreen.ViewModes & ~(HIRES | LACE | EXTRA_HALFBRITE);
  250. X
  251. X        if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, ORHI))
  252. X            -> Flags & CHECKED)
  253. X            newmode |= HIRES;
  254. X        if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, ORILC))
  255. X            -> Flags & CHECKED)
  256. X            newmode |= LACE;
  257. X        if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, OREHB))
  258. X            -> Flags & CHECKED)
  259. X            newmode |= EXTRA_HALFBRITE;
  260. X        if (newmode != MandelNScreen.ViewModes) {
  261. X            MandelNScreen.ViewModes = newmode;
  262. X            if (Sure())
  263. X            ReInitDisplay();
  264. X            else
  265. X            UpdateOptViewResCm();
  266. X        }
  267. X        }
  268. X        break;
  269. X    case ORBCK:
  270. X        if (ItemAddress(MandelMenu, MENU(OPTMENU,OPTRES,ORBCK))->Flags & CHECKED)
  271. X        DoBorderless(MainWindow, &borderinfo);
  272. X        else
  273. X        UndoBorderless(MainWindow, &borderinfo);
  274. X    } /* End Switch SUBNUM */
  275. X    break;
  276. X    case OPTPAR:
  277. X    Parameters();
  278. X    break;
  279. X    case OPTPRI:
  280. X    switch (SubNum) {
  281. X    case OPNOR:
  282. X        SetDrawPri(0);
  283. X        break;
  284. X    case OPLOW:
  285. X        SetDrawPri(-5);
  286. X        break;
  287. X    }
  288. X    break;
  289. X    } /* End Switch ITEMNUM */
  290. X}
  291. X
  292. X/*
  293. X *  This function sets the drawing function, numbered from 0.
  294. X */
  295. X
  296. Xvoid SetDrawingFunction(number)
  297. Xint number;
  298. X{
  299. X    if (number >= 0 && number <= DF5) {
  300. X    FunctionNr = number;
  301. X    DepthFunc = DepthFuncArray[FunctionNr];
  302. X    }
  303. X}
  304. X
  305. X/*
  306. X *  This function sets the i plotting function, numbered from 0.
  307. X */
  308. X
  309. Xvoid SetIPlotFunction(number)
  310. Xint number;
  311. X{
  312. X    if (number >= 0 && number <= DIZ) {
  313. X    IPlotNr = number;
  314. X    IPlotFunc = IPlotFuncArray[IPlotNr];
  315. X    }
  316. X}
  317. X
  318. X/*
  319. X *  This function sets the e plotting function, numbered from 0.
  320. X */
  321. X
  322. Xvoid SetEPlotFunction(number)
  323. Xint number;
  324. X{
  325. X    if (number >= 0 && number <= DEZ) {
  326. X    EPlotNr = number;
  327. X    EPlotFunc = EPlotFuncArray[EPlotNr];
  328. X    }
  329. X}
  330. X
  331. Xvoid DrwMenu(Code)
  332. XUSHORT Code;
  333. X{
  334. X    int ItemNum = ITEMNUM(Code);
  335. X    int SubNum = SUBNUM(Code);
  336. X
  337. X    switch (ItemNum) {
  338. X    case DRWFUN:
  339. X    SetDrawingFunction(SubNum + DF1);
  340. X    break;
  341. X    case DRWIPL:
  342. X    SetIPlotFunction(SubNum + DINONE);
  343. X    break;
  344. X    case DRWEPL:
  345. X    SetEPlotFunction(SubNum + DEDEPTH);
  346. X    break;
  347. X    }
  348. X}
  349. X
  350. Xvoid UnImpl()
  351. X{
  352. X    static char alert[] = "\
  353. X\0\144\25Mandelbrot Construction Set -- By KosmoSoft Productions\0a\
  354. X\0\170\40Sorry, this function has not been implemented yet!\0";
  355. X    DisplayAlert(RECOVERY_ALERT, alert, 50L);
  356. X}
  357. X
  358. XSTATIC USHORT OldMinWidth, OldMinHeight, OldMaxWidth, OldMaxHeight;
  359. X
  360. X/* Do not nest calls to DisableSizing: the original values will be lost. */
  361. X
  362. Xvoid DisableSizing()
  363. X{
  364. X    OldMinWidth = MainWindow->MinWidth;
  365. X    OldMaxWidth = MainWindow->MaxWidth;
  366. X    OldMinHeight = MainWindow->MinHeight;
  367. X    OldMaxHeight = MainWindow->MaxHeight;
  368. X    WindowLimits(MainWindow, (long) MainWindow->Width, (long) MainWindow->Height,
  369. X            (long) MainWindow->Width, (long) MainWindow->Height);
  370. X}
  371. X
  372. Xvoid EnableSizing()
  373. X{
  374. X    WindowLimits(MainWindow, (long) OldMinWidth, (long) OldMinHeight,
  375. X            (long) OldMaxWidth, (long) OldMaxHeight);
  376. X}
  377. X
  378. XSTATIC void PrjNew(SubNum)
  379. XUSHORT SubNum;
  380. X{
  381. X    struct Window *window;
  382. X    int ID;
  383. X    static double HShift = 0.0,
  384. X          VShift = 0.0;
  385. X    static double Factor = 3.0;
  386. X    double Width = RightEdge - LeftEdge,
  387. X       Height = TopEdge - BottomEdge,
  388. X       NewLeftEdge = LeftEdge,
  389. X       NewTopEdge = TopEdge,
  390. X       NewRightEdge = RightEdge,
  391. X       NewBottomEdge = BottomEdge;
  392. X
  393. X    /* Stuff for the ABSOLUTE requester */
  394. X
  395. X    static struct IntuiText RatioText = {
  396. X    MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 90, NULL,
  397. X    (UBYTE *) "Ratio:                    ", NULL    };
  398. X    static struct IntuiText AbsText = {
  399. X    MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL,
  400. X    (UBYTE *) "Select an absolute position", &RatioText };
  401. X    static struct IntuiText LRTBText[] = {
  402. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  403. X        (UBYTE *) "Left", NULL  },
  404. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  405. X        (UBYTE *) "Right", NULL },
  406. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  407. X        (UBYTE *) "Top", NULL   },
  408. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  409. X        (UBYTE *) "Bottom", NULL    }
  410. X    };
  411. X    static struct StringInfo LRTBinfo[] = {
  412. X    {   &Buffer[0][0], &Buffer[4][0], 0, 20, 0  },
  413. X    {   &Buffer[1][0], &Buffer[4][0], 0, 20, 0  },
  414. X    {   &Buffer[2][0], &Buffer[4][0], 0, 20, 0  },
  415. X    {   &Buffer[3][0], &Buffer[4][0], 0, 20, 0  }
  416. X    };
  417. X    static struct Gadget LRTBGadget[] = {
  418. X    {   &LRTBGadget[1], 66, 30, 160, 10,        /* next, LTWH */
  419. X        GADGHCOMP,                    /* Flags */
  420. X        RELVERIFY,                    /* Activation */
  421. X        STRGADGET | REQGADGET,            /* GadgetType */
  422. X        (APTR) NULL, NULL,                          /* rendering */
  423. X        &LRTBText[0], 0, (APTR) &LRTBinfo[0],       /* "Left" */
  424. X        NEGGADGETID+1, NULL },
  425. X    {   &LRTBGadget[2], 66, 45, 160, 10,        /* next, LTWH */
  426. X        GADGHCOMP,
  427. X        RELVERIFY,
  428. X        STRGADGET | REQGADGET,
  429. X        (APTR) NULL, NULL,
  430. X        &LRTBText[1], 0, (APTR) &LRTBinfo[1],       /* Right */
  431. X        NEGGADGETID+1, NULL },
  432. X    {   &LRTBGadget[3], 66, 60, 160, 10,        /* next, LTWH */
  433. X        GADGHCOMP,
  434. X        RELVERIFY,
  435. X        STRGADGET | REQGADGET,
  436. X        (APTR) NULL, NULL,
  437. X        &LRTBText[2], 0, (APTR) &LRTBinfo[2],       /* Top */
  438. X        NEGGADGETID+1, NULL },
  439. X    {   NULL, 66, 75, 160, 10,            /* next, LTWH */
  440. X        GADGHCOMP,
  441. X        RELVERIFY,
  442. X        STRGADGET | REQGADGET,
  443. X        (APTR) NULL, NULL,
  444. X        &LRTBText[3], 0, (APTR) &LRTBinfo[3],       /* Bottom */
  445. X        NEGGADGETID+1, NULL }
  446. X    };
  447. X    static struct Requester AbsRequest = {
  448. X    NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL,
  449. X    &AbsText, 0, 1    };
  450. X
  451. X    /* Stuff for the SHIFT requester */
  452. X
  453. X    static struct IntuiText ShiftText = {
  454. X    MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL,
  455. X    (UBYTE *) "Select a window shift amount", NULL  };
  456. X    static struct IntuiText RDText[] = {
  457. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  458. X        (UBYTE *) "Right", NULL },
  459. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  460. X        (UBYTE *) "Down", NULL  }
  461. X    };
  462. X    static struct Gadget RDGadget[] = {
  463. X    {   &RDGadget[1], 66, 45, 160, 10,        /* next, LTWH */
  464. X        GADGHCOMP,
  465. X        0,
  466. X        STRGADGET | REQGADGET,
  467. X        (APTR) NULL, NULL,
  468. X        &RDText[0], 0, (APTR) &LRTBinfo[0],     /* Right */
  469. X        0, NULL },
  470. X    {   NULL, 66, 60, 160, 10,            /* next, LTWH */
  471. X        GADGHCOMP,
  472. X        0,
  473. X        STRGADGET | REQGADGET,
  474. X        (APTR) NULL, NULL,
  475. X        &RDText[1], 0, (APTR) &LRTBinfo[1],     /* Down */
  476. X        0, NULL }
  477. X    };
  478. X    static struct Requester ShiftRequest = {
  479. X    NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL,
  480. X    &ShiftText, 0, 1    };
  481. X
  482. X    /* Stuff for the ZOOM requester */
  483. X
  484. X    static struct IntuiText ZoomText = {
  485. X    MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL,
  486. X    (UBYTE *) "Select a zoom center", NULL  };
  487. X    static struct IntuiText RIFText[] = {
  488. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  489. X        (UBYTE *) "X:Real", NULL },
  490. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  491. X        (UBYTE *) "Y:Imag", NULL  },
  492. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL,
  493. X        (UBYTE *) "Factor", NULL  }
  494. X    };
  495. X    static struct Gadget RIFGadget[] = {
  496. X    {   &RIFGadget[1], 66, 30, 160, 10,         /* next, LTWH */
  497. X        GADGHCOMP,
  498. X        0,
  499. X        STRGADGET | REQGADGET,
  500. X        (APTR) NULL, NULL,
  501. X        &RIFText[0], 0, (APTR) &LRTBinfo[0],    /* Re */
  502. X        0, NULL },
  503. X    {   &RIFGadget[2], 66, 45, 160, 10,        /* next, LTWH */
  504. X        GADGHCOMP,
  505. X        0,
  506. X        STRGADGET | REQGADGET,
  507. X        (APTR) NULL, NULL,
  508. X        &RIFText[1], 0, (APTR) &LRTBinfo[1],    /* Im */
  509. X        0, NULL },
  510. X    {   NULL, 66, 60, 160, 10,            /* next, LTWH */
  511. X        GADGHCOMP,
  512. X        0,
  513. X        STRGADGET | REQGADGET,
  514. X        (APTR) NULL, NULL,
  515. X        &RIFText[2], 0, (APTR) &LRTBinfo[2],    /* Factor */
  516. X        0, NULL }
  517. X    };
  518. X    static struct Requester ZoomRequest = {
  519. X    NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL,
  520. X    &ZoomText, 0, 1    };
  521. X
  522. X    switch (SubNum) {
  523. X    case PNRED:
  524. X    if (MouseStatus != FLASHING) return;
  525. X    else {
  526. X        register SHORT w = MainWindow -> GZZWidth,
  527. X               h = MainWindow -> GZZHeight;
  528. X        register SHORT X1, Y1, X2, Y2;
  529. X
  530. X        /* If you cast less, Aztec seems to do it wrong... */
  531. X        X1 = (-(long)FrameX1 * w) / ((long)FrameX2 - (long)FrameX1);
  532. X        Y1 = (-(long)FrameY1 * h) / ((long)FrameY2 - (long)FrameY1);
  533. X        X2 = ((long)(w-1-FrameX1) * w) / ((long)FrameX2 - (long)FrameX1)
  534. X        - 1;
  535. X        Y2 = ((long)(h-1-FrameY1) * h) / ((long)FrameY2 - (long)FrameY1)
  536. X        - 1;
  537. X
  538. X        NewLeftEdge   = LeftEdge + X1 * CXStep;
  539. X        NewRightEdge  = LeftEdge + X2 * CXStep;
  540. X        NewTopEdge      =  TopEdge - Y1 * CYStep;
  541. X        NewBottomEdge =  TopEdge - Y2 * CYStep;
  542. X
  543. X        skipto pnabs;
  544. X    }
  545. X    case PNENL:
  546. X    if (MouseStatus != FLASHING) return;
  547. X
  548. X    NewLeftEdge   = LeftEdge + FrameX1 * CXStep;
  549. X    NewRightEdge  = LeftEdge + FrameX2 * CXStep;
  550. X    NewTopEdge    =  TopEdge - FrameY1 * CYStep;
  551. X    NewBottomEdge =  TopEdge - FrameY2 * CYStep;
  552. X    skipto pnabs;
  553. X    case PNSHF:
  554. X    NegativeGadget.NextGadget = &RDGadget[0];
  555. X    do {
  556. X        sprintf(Buffer[0], "%1.6g",HShift);
  557. X        sprintf(Buffer[1], "%1.6g",VShift);
  558. X
  559. X        window = MyRequest(&ShiftRequest, MainWindow);
  560. X        ID = WaitMyRequest(window);
  561. X        EndMyRequest(&ShiftRequest, window, MainWindow);
  562. X        if (ID == NEGGADGETID) return;
  563. X
  564. X    } while (sscanf(Buffer[0], "%lf", &HShift)+
  565. X        sscanf(Buffer[1], "%lf", &VShift) != 2);
  566. X
  567. X    NewLeftEdge   = LeftEdge + HShift * Width;
  568. X    NewRightEdge  = RightEdge + HShift * Width;
  569. X    NewTopEdge    = TopEdge - VShift * Height;
  570. X    NewBottomEdge = BottomEdge - VShift * Height;
  571. X
  572. X    skipto pnabs;
  573. X    case PNZI:
  574. X    case PNZO: {
  575. X    double ReMid, ImMid;
  576. X
  577. X    if (MouseStatus == NOTFRAMING) {
  578. X        ReMid = (RightEdge + LeftEdge) / 2.0;
  579. X        ImMid = (TopEdge + BottomEdge) / 2.0;
  580. X    } else {
  581. X        ReMid = ReMouse;
  582. X        ImMid = ImMouse;
  583. X    }
  584. X
  585. X    NegativeGadget.NextGadget = &RIFGadget[0];
  586. X    do {
  587. X        sprintf(Buffer[0], "%1.6g",ReMid);
  588. X        sprintf(Buffer[1], "%1.6g",ImMid);
  589. X        sprintf(Buffer[2], "%1.6g",Factor);
  590. X
  591. X        window = MyRequest(&ZoomRequest, MainWindow);
  592. X        ID = WaitMyRequest(window);
  593. X        EndMyRequest(&ZoomRequest, window, MainWindow);
  594. X        if (ID == NEGGADGETID) return;
  595. X
  596. X    } while (sscanf(Buffer[0], "%lf", &ReMid)+
  597. X         sscanf(Buffer[1], "%lf", &ImMid)+
  598. X         sscanf(Buffer[2], "%lf", &Factor) != 3);
  599. X    if (SubNum == PNZI) {
  600. X        if (Factor == 0.0) {
  601. X        Factor = 1.0;
  602. X        }
  603. X        Width /= Factor;
  604. X        Height /= Factor;
  605. X    } else {
  606. X        Width *= Factor;
  607. X        Height *= Factor;
  608. X    }
  609. X    NewLeftEdge   = ReMid - Width / 2.0;
  610. X    NewTopEdge    = ImMid + Height / 2.0;
  611. X    NewRightEdge  = NewLeftEdge + Width;
  612. X    NewBottomEdge = NewTopEdge - Height;
  613. X    skipto pnabs;
  614. X    }
  615. X    case PNABS:
  616. X    NewLeftEdge = LeftEdge;
  617. X    NewRightEdge = RightEdge;
  618. X    NewTopEdge = TopEdge;
  619. X    NewBottomEdge = BottomEdge;
  620. X
  621. Xpnabs:
  622. X    NegativeGadget.NextGadget = &LRTBGadget[0];
  623. X    sprintf(Buffer[0], "%1.10g", NewLeftEdge);
  624. X    sprintf(Buffer[1], "%1.10g", NewRightEdge);
  625. X    sprintf(Buffer[2], "%1.10g", NewTopEdge);
  626. X    sprintf(Buffer[3], "%1.10g", NewBottomEdge);
  627. X    sprintf(RatioText.IText+7, "%1.4f     ", Ratio(NewLeftEdge,
  628. X        NewRightEdge, NewTopEdge, NewBottomEdge, MainWindow));
  629. X
  630. X    do {
  631. X        window = MyRequest(&AbsRequest, MainWindow);
  632. X
  633. X        while ( (ID = WaitMyRequest(window) ) > NEGGADGETID) {
  634. X        sscanf(Buffer[0], "%lf", &NewLeftEdge);
  635. X        sscanf(Buffer[1], "%lf", &NewRightEdge);
  636. X        sscanf(Buffer[2], "%lf", &NewTopEdge);
  637. X        sscanf(Buffer[3], "%lf", &NewBottomEdge);
  638. X        sprintf(RatioText.IText+7, "%1.4f     ",
  639. X            Ratio(NewLeftEdge, NewRightEdge, NewTopEdge,
  640. X            NewBottomEdge, MainWindow));
  641. X
  642. X        PrintIText(AbsRequest.ReqLayer->rp, &RatioText, 0L, 0L);
  643. X        }
  644. X
  645. X        EndMyRequest(&AbsRequest, window, MainWindow);
  646. X
  647. X    } while (sscanf(Buffer[0], "%lf", &NewLeftEdge)+
  648. X         sscanf(Buffer[1], "%lf", &NewRightEdge)+
  649. X         sscanf(Buffer[2], "%lf", &NewTopEdge)+
  650. X         sscanf(Buffer[3], "%lf", &NewBottomEdge) < 4);
  651. X
  652. X    if (ID != POSGADGETID) return;
  653. X
  654. X    LeftEdge = NewLeftEdge;
  655. X    RightEdge = NewRightEdge;
  656. X    TopEdge = NewTopEdge;
  657. X    BottomEdge = NewBottomEdge;
  658. X
  659. X    StopFraming();
  660. X    StopDrawing();
  661. X
  662. X    break;
  663. X    }
  664. X    DrawPicture((bool)FALSE);   /* Don't fill in */
  665. X}
  666. X
  667. Xfloat Ratio(l, r, t, b, window)
  668. Xdouble l, r, t, b;
  669. Xstruct Window *window;
  670. X{
  671. X    float PixelRatio;
  672. X    float ReImRatio;
  673. X
  674. X    if (t == b) t = b+1;    /* You never know... */
  675. X
  676. X    PixelRatio = (float) window->GZZWidth / window->GZZHeight;
  677. X
  678. X    if (window->WScreen->ViewPort.Modes & HIRES) PixelRatio /= 2;
  679. X    if (window->WScreen->ViewPort.Modes & LACE) PixelRatio *= 2;
  680. X    ReImRatio = (r - l)/(t - b);
  681. X
  682. X    return ReImRatio / PixelRatio;
  683. X}
  684. X
  685. Xvoid Parameters()
  686. X{
  687. X    struct Window *window;
  688. X    int ID;
  689. X    int NewMaxDepth, NewRangeWidth, NewWBwidth, NewWBheight;
  690. X
  691. X    static struct IntuiText ParamText = {
  692. X    MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL,
  693. X    (UBYTE *) "Select these parameters", NULL   };
  694. X    static struct IntuiText ParmText[] = {
  695. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL,
  696. X        (UBYTE *) "Max depth", NULL },
  697. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL,
  698. X        (UBYTE *) "Range width", NULL   },
  699. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL,
  700. X        (UBYTE *) "Screen width", NULL  },
  701. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL,
  702. X        (UBYTE *) "Screen height", NULL  }
  703. X    };
  704. X    static struct StringInfo Parminfo[] = {
  705. X    {   &Buffer[0][0], &Buffer[4][0], 0, 20, 0  },
  706. X    {   &Buffer[1][0], &Buffer[4][0], 0, 20, 0  },
  707. X    {   &Buffer[2][0], &Buffer[4][0], 0, 20, 0  },
  708. X    {   &Buffer[3][0], &Buffer[4][0], 0, 20, 0  }
  709. X    };
  710. X    static struct Gadget ParmGadget[] = {
  711. X    {   &ParmGadget[1], 130, 30, 96, 10,        /* next, LTWH */
  712. X        GADGHCOMP,                    /* Flags */
  713. X        RELVERIFY | LONGINT,            /* Activation */
  714. X        STRGADGET | REQGADGET,            /* GadgetType */
  715. X        (APTR) NULL, NULL,                          /* rendering */
  716. X        &ParmText[0], 0, (APTR) &Parminfo[0],       /* "MaxDepth" */
  717. X        0, NULL },
  718. X    {   &ParmGadget[2], 130, 45, 96, 10,        /* next, LTWH */
  719. X        GADGHCOMP,
  720. X        RELVERIFY | LONGINT,
  721. X        STRGADGET | REQGADGET,
  722. X        (APTR) NULL, NULL,
  723. X        &ParmText[1], 0, (APTR) &Parminfo[1],       /* "RangeWidth" */
  724. X        0, NULL },
  725. X    {   &ParmGadget[3], 130, 60, 96, 10,        /* next, LTWH */
  726. X        GADGHCOMP,
  727. X        RELVERIFY | LONGINT,
  728. X        STRGADGET | REQGADGET,
  729. X        (APTR) NULL, NULL,
  730. X        &ParmText[2], 0, (APTR) &Parminfo[2],       /* "Screen width" */
  731. X        0, NULL },
  732. X    {   NULL, 130, 75, 96, 10,            /* next, LTWH */
  733. X        GADGHCOMP,
  734. X        RELVERIFY | LONGINT,
  735. X        STRGADGET | REQGADGET,
  736. X        (APTR) NULL, NULL,
  737. X        &ParmText[3], 0, (APTR) &Parminfo[3],       /* "Screen height" */
  738. X        0, NULL }
  739. X    };
  740. X    static struct Requester ParmRequest = {
  741. X    NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL,
  742. X    &ParamText, 0, 1    };
  743. X
  744. X    /* Stuff for the PARAMETERS requester */
  745. X    NegativeGadget.NextGadget = &ParmGadget[0];
  746. X    Parminfo[0].LongInt = MaxDepth;
  747. X    Parminfo[1].LongInt = RangeWidth;
  748. X    Parminfo[2].LongInt = WBWidth;
  749. X    Parminfo[3].LongInt = WBHeight;
  750. X    do {
  751. X    sprintf(Buffer[0], "%ld", Parminfo[0].LongInt);
  752. X    sprintf(Buffer[1], "%ld", Parminfo[1].LongInt);
  753. X    sprintf(Buffer[2], "%ld", Parminfo[2].LongInt);
  754. X    sprintf(Buffer[3], "%ld", Parminfo[3].LongInt);
  755. X
  756. X    window = MyRequest(&ParmRequest, MainWindow);
  757. X    ID = WaitMyRequest(window);
  758. X    EndMyRequest(&ParmRequest, window, MainWindow);
  759. X    if (ID == NEGGADGETID) return;
  760. X
  761. X    NewMaxDepth   = Parminfo[0].LongInt;
  762. X    NewRangeWidth = Parminfo[1].LongInt;
  763. X    NewWBwidth    = Parminfo[2].LongInt;
  764. X    NewWBheight   = Parminfo[3].LongInt;
  765. X    } while ( NewMaxDepth < 0 || NewMaxDepth > MAXDEPTH ||
  766. X          NewRangeWidth < 0 || NewRangeWidth > MAXDEPTH );
  767. X
  768. X    if (NewRangeWidth != RangeWidth)    InitPenTable();
  769. X    MaxDepth = NewMaxDepth;
  770. X    RangeWidth = NewRangeWidth;
  771. X
  772. X    if ((NewWBwidth != WBWidth || NewWBheight != WBHeight) && Sure()) {
  773. X     WBWidth = NewWBwidth;
  774. X     WBHeight = NewWBheight;
  775. X     ReInitDisplay();
  776. X    }
  777. X}
  778. X
  779. Xvoid UpdateCheckmarks()
  780. X{
  781. X    UpdateOptColorCm();
  782. X    UpdateOptDrawResCm();
  783. X    UpdateOptViewResCm();
  784. X    UpdateOptPriCm();
  785. X    UpdateDrwCm();
  786. X}
  787. X
  788. Xvoid UpdateOptColorCm()
  789. X{
  790. X    SelectMenu(MENU(OPTMENU, OPTCOL, OCSEL), (bool)(PenTableMode == SELECT));
  791. X    SelectMenu(MENU(OPTMENU, OPTCOL, OCMOD), (bool)(PenTableMode == MODULO));
  792. X    SelectMenu(MENU(OPTMENU, OPTCOL, OCRAN), (bool)(PenTableMode == RANGES));
  793. X}
  794. X
  795. Xvoid UpdateOptDrawResCm()
  796. X{
  797. X    SelectMenu(MENU(OPTMENU, OPTRES, ORNRM), (bool)(PixelStep == 1));
  798. X    SelectMenu(MENU(OPTMENU, OPTRES, OR12 ), (bool)(PixelStep == 2));
  799. X    SelectMenu(MENU(OPTMENU, OPTRES, OR13 ), (bool)(PixelStep == 3));
  800. X    SelectMenu(MENU(OPTMENU, OPTRES, OR14 ), (bool)(PixelStep == 4));
  801. X}
  802. X
  803. Xvoid UpdateOptViewResCm()
  804. X{
  805. X    SelectMenu(MENU(OPTMENU, OPTRES, ORHI ),
  806. X           (bool)((MandelNScreen.ViewModes & HIRES) != 0));
  807. X    SelectMenu(MENU(OPTMENU, OPTRES, ORILC),
  808. X           (bool)((MandelNScreen.ViewModes & LACE) != 0));
  809. X    SelectMenu(MENU(OPTMENU, OPTRES, OREHB),
  810. X           (bool)((MandelNScreen.ViewModes & EXTRA_HALFBRITE) != 0));
  811. X    SelectMenu(MENU(OPTMENU, OPTRES, ORBCK),
  812. X           (bool)((MainWindow->Flags & BORDERLESS) != 0));
  813. X}
  814. X
  815. Xvoid UpdateOptPriCm()
  816. X{
  817. X    SelectMenu(MENU(OPTMENU, OPTPRI, OPNOR), (bool)(DrawPri == 0));
  818. X    SelectMenu(MENU(OPTMENU, OPTPRI, OPLOW), (bool)(DrawPri <  0));
  819. X}
  820. X
  821. Xvoid UpdateFunCm()
  822. X{
  823. X    SelectMenu(MENU(DRWMENU, DRWFUN, DF1), (bool)(FunctionNr == DF1-DF1));
  824. X    SelectMenu(MENU(DRWMENU, DRWFUN, DF2), (bool)(FunctionNr == DF2-DF1));
  825. X    SelectMenu(MENU(DRWMENU, DRWFUN, DF3), (bool)(FunctionNr == DF3-DF1));
  826. X    SelectMenu(MENU(DRWMENU, DRWFUN, DFUPF), (bool)(FunctionNr == DFUPF-DF1));
  827. X    SelectMenu(MENU(DRWMENU, DRWFUN, DF5), (bool)(FunctionNr == DF5-DF1));
  828. X}
  829. X
  830. Xvoid UpdateIPlotCm()
  831. X{
  832. X    SelectMenu(MENU(DRWMENU, DRWIPL, DINONE), (bool)(IPlotNr == DINONE-DINONE));
  833. X    SelectMenu(MENU(DRWMENU, DRWIPL, DIZ)   , (bool)(IPlotNr == DIZ-DINONE));
  834. X}
  835. X
  836. Xvoid UpdateEPlotCm()
  837. X{
  838. X    SelectMenu(MENU(DRWMENU, DRWEPL, DEDEPTH), (bool)(EPlotNr == DEDEPTH-DEDEPTH));
  839. X    SelectMenu(MENU(DRWMENU, DRWEPL, DEZ)    , (bool)(EPlotNr == DEZ-DEDEPTH));
  840. X}
  841. X
  842. Xvoid UpdateDrwCm()
  843. X{
  844. X    UpdateFunCm();
  845. X    UpdateIPlotCm();
  846. X    UpdateEPlotCm();
  847. X}
  848. SHAR_EOF
  849. echo "extracting Jiff.c"
  850. sed 's/^X//' << \SHAR_EOF > Jiff.c
  851. X
  852. X/*
  853. X * JIFF.H
  854. X */
  855. X
  856. X#define XMAX 640
  857. X#define LOXMAX 320
  858. X#define YMAX 200
  859. X#define XASPECT 5
  860. X#define YASPECT 11
  861. X
  862. X/*
  863. X * EA handy make a long from 4 chars macros redone to work with Aztec
  864. X */
  865. X#define MAKE_ID(a, b, c, d)\
  866. X( ((long)(a)<<24) | ((long)(b)<<16) | ((long)(c)<<8) | (long)(d) )
  867. X
  868. X/*
  869. X * These are the IFF types I deal with
  870. X */
  871. X#define FORM MAKE_ID('F', 'O', 'R', 'M')
  872. X#define ILBM MAKE_ID('I', 'L', 'B', 'M')
  873. X#define BMHD MAKE_ID('B', 'M', 'H', 'D')
  874. X#define CMAP MAKE_ID('C', 'M', 'A', 'P')
  875. X#define BODY MAKE_ID('B', 'O', 'D', 'Y')
  876. X
  877. X/*
  878. X * And these are the IFF types I ignore but don't squawk about
  879. X */
  880. X#define GRAB MAKE_ID('G', 'R', 'A', 'B')
  881. X#define DEST MAKE_ID('D', 'E', 'S', 'T')
  882. X#define SPRT MAKE_ID('S', 'P', 'R', 'T')
  883. X#define CAMG MAKE_ID('C', 'A', 'M', 'G')
  884. X#define CRNG MAKE_ID('C', 'R', 'N', 'G')
  885. X#define CCRT MAKE_ID('C', 'C', 'R', 'T')
  886. X
  887. X#define EVEN(x) (((x) + 1) & ~1)
  888. X#define MANDEL
  889. X
  890. X/*
  891. X * Some macros for raster memory allocation ... redefine if you're
  892. X * sensible and manage memory locally
  893. X */
  894. X
  895. X#ifndef MANDEL
  896. X
  897. X/*
  898. X * ralloc - raster alloc
  899. X */
  900. X# define ralloc(amount)  (PLANEPTR)AllocMem((long)(amount), MEMF_CHIP)
  901. X/*
  902. X * rfree - raster free
  903. X */
  904. X# define rfree(pt, amount)  FreeMem( (pt), (long)(amount) )
  905. X
  906. X#else                /* MANDEL */
  907. X
  908. X# include <mandel.h>
  909. X
  910. X/*
  911. X * We don't want to allocate a complete raster for the picture, since we
  912. X * already have a screen with a window where we want to have it.
  913. X * Therefore, we allocate some small buffers, which get blitted into our
  914. X * window as soon as they fill up.
  915. X */
  916. X# define MAXPLANESIZE    1040L
  917. X/*
  918. X * ralloc - raster alloc
  919. X */
  920. X# define ralloc(amount) (PLANEPTR)AllocMem(MAXPLANESIZE, MEMF_CHIP | MEMF_CLEAR)
  921. X/*
  922. X * rfree - raster free
  923. X */
  924. X# define rfree(pt, amount)  FreeMem( (pt), MAXPLANESIZE )
  925. X
  926. X#endif                /* !MANDEL */
  927. X
  928. X/*
  929. X * line_bytes = the number of words * 2 (for bytes) a raster line takes up
  930. X */
  931. X#define line_bytes(width)   ((((width) + 15) >> 3) & ~0x0001)
  932. X
  933. X/*
  934. X * psize - plane size in bytes (an even number) of a raster given width
  935. X * and height
  936. X */
  937. X#define psize(width, height) ( line_bytes(width)*height)
  938. X
  939. X/*
  940. X * The place to throw excess bits
  941. X */
  942. X#define bit_bucket(file, length) fseek(file, (long)EVEN(length), 1)
  943. X
  944. X
  945. Xunion bytes4 {
  946. X    char        b4_name[4];
  947. X    LONG        b4_type;
  948. X};
  949. X
  950. Xstruct iff_chunk {
  951. X    union bytes4    iff_type;
  952. X    LONG        iff_length;
  953. X};
  954. X
  955. Xstruct form_chunk {
  956. X    union bytes4    fc_type;    /* == FORM */
  957. X    LONG        fc_length;
  958. X    union bytes4    fc_subtype;
  959. X};
  960. X
  961. Xstruct CommodoreAmiga {
  962. X    struct iff_chunk camg_iffc; /* == CAMG */
  963. X    LONG        camg_data;
  964. X};
  965. X
  966. X#ifndef MANDEL            /* We have this already in Mandel.h */
  967. Xstruct BitMapHeader {
  968. X    UWORD        w,
  969. X            h;
  970. X    UWORD        x,
  971. X            y;
  972. X    UBYTE        nPlanes;
  973. X    UBYTE        masking;
  974. X    UBYTE        compression;
  975. X    UBYTE        pad1;
  976. X    UWORD        transparentColor;
  977. X    UBYTE        xAspect,
  978. X            yAspect;
  979. X    WORD        pageWidth,
  980. X            pageHeight;
  981. X};
  982. X
  983. X/*
  984. X * ILBM_info is the structure win_read_iff returns, and is hopefully all
  985. X * you need to deal with out of the iff reader routines below
  986. X */
  987. Xstruct ILBM_info {
  988. X    struct BitMapHeader header;
  989. X    UBYTE        cmap[MAXCOL * 3];
  990. X    struct BitMap   bitmap;
  991. X#ifdef MANDEL
  992. X    struct Mand    *mand;
  993. X    long        mandsize;
  994. X#endif
  995. X};
  996. X
  997. X#endif                /* !MANDEL */
  998. X
  999. X/*-
  1000. X * I sure wish C function "prototypes" were real and not just ANSI
  1001. X *
  1002. X * extern struct ILBM_info *win_read_iff();
  1003. X * win_read_iff( char *filename, short just_colors, int MandSize,
  1004. X *          APTR MandPointer );
  1005. X * extern void free_planes();  free_planes( struct BitMap *bitmap);
  1006. X * extern int write_iff();
  1007. X * write_iff(char *name, unsigned char *colors, struct Window *window,
  1008. X *  short xoff, short yoff, short compressed);
  1009. X */
  1010. X
  1011. X/*
  1012. X * Anyone know where some useful minterms are defined?
  1013. X */
  1014. X#define COPY_MINTERM        0x0C0L
  1015. X
  1016. X/***
  1017. X
  1018. X    A meditation for the guru from the Diamond Sutra -
  1019. X
  1020. X    So shall you think of all this fleeting world:
  1021. X    A star at dawn, a bubble in a stream;
  1022. X    A flash of lightning in a summer cloud,
  1023. X    A flickering lamp, a phantom, and a dream.
  1024. X
  1025. X***/
  1026. X
  1027. X
  1028. X/*
  1029. X * jiff.c   Jim Kent's iff - ilbm  reader
  1030. X *
  1031. X * This is the (sortof) short (sortof) simple no-frills IFF reader to get
  1032. X * something out of DPaint, Images, or the Animator.  It works well with
  1033. X * the Aztec C compiler.  It should work with Lattice but you never know
  1034. X * until you try it.    I haven't.
  1035. X *
  1036. X * I've included a simple main program.  This is just to make it stand alone.
  1037. X * Since amiga screen initializations are massive, all it does as is is
  1038. X * read it into a BitMap, and then free up the BitMap. Should crash it if
  1039. X * it's gonna crash though.
  1040. X *
  1041. X * The main interface to this is through the routine win_read_iff(filename).
  1042. X * This returns a ILBM_info structure-pointer on success, and NULL on
  1043. X * failure.  It cleans up after itself on failure.
  1044. X *
  1045. X * I hope you will find this useful and easy to use.  Please forgive my funky
  1046. X * indentation style?  Well at least I'm consistent! (* Run through the
  1047. X * C-Beautifier by Olaf Seibert !! *)
  1048. X *
  1049. X * To demonstrate what a nice guy I am even though I'm far from wild about
  1050. X * the IFF standard I'm placing this in the public domain.  When you
  1051. X * remove the DEBUG and PARANOID definitions the code is only 1536 bytes
  1052. X * long.
  1053. X *
  1054. X * -Jim Kent  April 22, 1986
  1055. X */
  1056. X
  1057. X
  1058. X#include <stdio.h>
  1059. X#include <exec/types.h>
  1060. X#include <exec/memory.h>
  1061. X#include <graphics/gfx.h>
  1062. X#include <libraries/dos.h>
  1063. X#include <intuition/intuition.h>
  1064. X/* #include "jiff.h"    */
  1065. X
  1066. X
  1067. X/*
  1068. X * This is an all too common state of software development.  Get rid of
  1069. X * this define as soon as it runs.
  1070. X */
  1071. X#undef DEBUG
  1072. X/* #define DEBUG/* */
  1073. X
  1074. X/*
  1075. X * This is the normal state of software development.  Seriously undefine
  1076. X * this to make it shut up about errors and reduce code size half way
  1077. X * through beta testing...
  1078. X */
  1079. X#undef PARANOID
  1080. X
  1081. X/*
  1082. X * This is nice if you want to use a debugger on the STATIC data and
  1083. X * routines in this file. Redefine only if you don't need a debugger.
  1084. X */
  1085. X
  1086. X#ifdef DEBUG
  1087. X# undef STATIC
  1088. X# define STATIC
  1089. X#endif
  1090. X
  1091. XSTATIC struct ILBM_info *win_read_ilbm();
  1092. XSTATIC struct ILBM_info *win_read_body();
  1093. X
  1094. X/*
  1095. X * OK this code is almost re-entrant.  Pass this guy from above to make it
  1096. X * really re-entrant.  (Why do you need a reentrant ILBM reader though??
  1097. X * Maybe for Dale ... ) Well, look in the IFF specs for instance... [Olaf
  1098. X * Seibert, KosmoSoft]
  1099. X */
  1100. XSTATIC struct ILBM_info root_info;    /* static so get initialized to
  1101. X                     * zero */
  1102. X
  1103. X
  1104. X#ifdef PARANOID
  1105. X/*
  1106. X * a little paranoid routine that say's where we got before EOF
  1107. X */
  1108. XSTATIC void
  1109. Xiff_truncated(where)
  1110. Xint        where;
  1111. X{
  1112. X    printf("ILBM truncated %d\n", where);
  1113. X    free_planes(&root_info.bitmap);
  1114. X}
  1115. X
  1116. X#endif PARANOID
  1117. X
  1118. X
  1119. Xstruct ILBM_info *
  1120. Xwin_read_iff(name, just_colors, window, MandSize, MandPointer)
  1121. Xchar           *name;
  1122. Xshort        just_colors;
  1123. Xstruct Window  *window;
  1124. Xint        MandSize;
  1125. XAPTR        MandPointer;
  1126. X{
  1127. X    struct ILBM_info *info = &root_info;
  1128. X    FILE       *file;
  1129. X    struct form_chunk chunk;
  1130. X
  1131. X    if ((file = fopen(name, "r")) == 0) {
  1132. X#ifdef PARANOID
  1133. X    printf("couldn't fopen %s to read\n", name);
  1134. X#endif PARANOID
  1135. X    return NULL;
  1136. X    }
  1137. X    if (fread(&chunk, sizeof (struct form_chunk), 1, file) != 1) {
  1138. X#ifdef PARANOID
  1139. X    iff_truncated(0);
  1140. X#endif PARANOID
  1141. X    fclose(file);
  1142. X    return NULL;
  1143. X    }
  1144. X    if (chunk.fc_type.b4_type != FORM) {
  1145. X#ifdef PARANOID
  1146. X    printf("not a FORM - %s\n", name);
  1147. X#endif PARANOID
  1148. X    fclose(file);
  1149. X    return NULL;
  1150. X    }
  1151. X    if (chunk.fc_subtype.b4_type != ILBM) {
  1152. X#ifdef PARANOID
  1153. X    printf("FORM not an ILBM - %s\n", name);
  1154. X#endif PARANOID
  1155. X    fclose(file);
  1156. X    return NULL;
  1157. X    }
  1158. X#ifdef DEBUG
  1159. X    printf("FORM %ld ILBM\n", chunk.fc_length);
  1160. X#endif DEBUG
  1161. X
  1162. X#ifdef MANDEL
  1163. X    info->mand = (struct Mand *) MandPointer;
  1164. X    info->mandsize = MandSize;
  1165. X    info->mand->MandID = 0;    /* we have not yet read it */
  1166. X#endif
  1167. X
  1168. X    info = win_read_ilbm(file, info, chunk.fc_length - sizeof (chunk),
  1169. X             just_colors, window);
  1170. X#ifdef DEBUG
  1171. X    printf("info = %lx\n", info);
  1172. X#endif DEBUG
  1173. X
  1174. X#ifdef MANDEL
  1175. X    /*
  1176. X     * Backward compatibility with non-standard code: We may want to read
  1177. X     * the extra MAND if we have not read it by now.
  1178. X     */
  1179. X    if (info && MandSize && info->mand->MandID != MAND) {
  1180. X    fread(MandPointer, 1, MandSize, file);
  1181. X    info->mand->Size -= 2 * sizeof (long);  /* patch bug */
  1182. X    }
  1183. X#endif MANDEL
  1184. X
  1185. X    fclose(file);
  1186. X
  1187. X    return info;
  1188. X}
  1189. X
  1190. XSTATIC struct ILBM_info *
  1191. Xwin_read_ilbm(file, info, length, just_colors, window)
  1192. XFILE           *file;
  1193. Xstruct ILBM_info *info;
  1194. Xlong        length;
  1195. Xshort        just_colors;
  1196. Xstruct Window  *window;
  1197. X{
  1198. X    struct iff_chunk chunk;
  1199. X    int         i;
  1200. X    long        read_in = 0;
  1201. X    int         got_header = FALSE; /* To make sure gots the header
  1202. X                     * first */
  1203. X    int         got_cmap = FALSE;    /* Make sure get cmap before
  1204. X                     * "BODY" */
  1205. X
  1206. X    /*
  1207. X     * Make sure the Planes are all NULL so can free up memory easily on
  1208. X     * error abort
  1209. X     */
  1210. X    for (i = 0; i < 8; i++)
  1211. X    info->bitmap.Planes[i] = NULL;
  1212. X
  1213. X    while (read_in < length) {
  1214. X    if (fread(&chunk, sizeof (chunk), 1, file) != 1) {
  1215. X#ifdef PARANOID
  1216. X        iff_truncated(1);
  1217. X#endif PARANOID
  1218. X        return NULL;
  1219. X    }
  1220. X    switch (chunk.iff_type.b4_type) {
  1221. X    case BMHD:
  1222. X#ifdef DEBUG
  1223. X        printf("\tBMHD %ld\n", chunk.iff_length);
  1224. X#endif DEBUG
  1225. X        if (fread(&info->header, sizeof (info->header), 1, file) != 1) {
  1226. X#ifdef PARANOID
  1227. X        iff_truncated(2);
  1228. X#endif PARANOID
  1229. X        return NULL;
  1230. X        }
  1231. X        got_header = TRUE;
  1232. X        break;
  1233. X    case CMAP:
  1234. X#ifdef DEBUG
  1235. X        printf("\tCMAP %ld\n", chunk.iff_length);
  1236. X#endif DEBUG
  1237. X        if (!got_header) {
  1238. X#ifdef PARANOID
  1239. X        printf("CMAP before BMHD\n");
  1240. X#endif PARANOID
  1241. X        return NULL;
  1242. X        }
  1243. X        if (chunk.iff_length <= 3 * MAXCOL) {
  1244. X        if (fread(info->cmap, (int) chunk.iff_length, 1, file) != 1) {
  1245. X#ifdef PARANOID
  1246. X            iff_truncated(3);
  1247. X#endif PARANOID
  1248. X            return NULL;
  1249. X        }
  1250. X        } else {
  1251. X#ifdef PARANOID
  1252. X        printf("warning, more than %d colors in ILBM CMAP\n",
  1253. X               MAXCOL);
  1254. X#endif PARANOID
  1255. X        if (fread(info->cmap, (int) 3 * MAXCOL, 1, file) != 1) {
  1256. X#ifdef PARANOID
  1257. X            iff_truncated(4);
  1258. X#endif PARANOID
  1259. X            return NULL;
  1260. X        }
  1261. X        bit_bucket(file, chunk.iff_length - 3 * MAXCOL);
  1262. X        }
  1263. X        got_cmap = TRUE;
  1264. X        if (just_colors)
  1265. X        return info;
  1266. X        break;
  1267. X    case MAND:
  1268. X#ifdef DEBUG
  1269. X        printf("\tMAND %ld\n", chunk.iff_length);
  1270. X#endif DEBUG
  1271. X        if (chunk.iff_length + sizeof (chunk) <= info->mandsize) {
  1272. X        if (fread((char *) info->mand + sizeof (chunk),
  1273. X              (int) chunk.iff_length, 1, file) != 1) {
  1274. X#ifdef DEBUG
  1275. X            printf("fread MAND fails; filepos %ld ferror %d\n",
  1276. X               (long) ftell(file), (int) ferror(file));
  1277. X#endif
  1278. X            return NULL;
  1279. X        }
  1280. X        *(struct iff_chunk *) info->mand = chunk;
  1281. X
  1282. X        /*
  1283. X         * skip padding byte
  1284. X         */
  1285. X        if (chunk.iff_length & 1)
  1286. X            getc(file);
  1287. X        } else {
  1288. X#ifdef DEBUG
  1289. X        printf("skipping MAND; too large for buffer (%ld)\n",
  1290. X               (long) info->mandsize);
  1291. X#endif
  1292. X        bit_bucket(file, chunk.iff_length);
  1293. X        }
  1294. X        break;
  1295. X    case BODY:
  1296. X        if (!got_cmap) {
  1297. X#ifdef PARANOID
  1298. X        printf("BODY before CMAP\n");
  1299. X#endif PARANOID
  1300. X        return NULL;
  1301. X        }
  1302. X#ifdef DEBUG
  1303. X        printf("\tBODY %ld\n", chunk.iff_length);
  1304. X#endif DEBUG
  1305. X        return win_read_body(file, info, chunk.iff_length, window);
  1306. X
  1307. X    default:        /* Squawk about unknown types if PARANOID */
  1308. X#ifdef PARANOID
  1309. X        printf("\t unknown type %lx of b4_type\n", chunk.iff_type.b4_type);
  1310. X    case GRAB:        /* Ignore documented but unwanted types */
  1311. X    case DEST:
  1312. X    case SPRT:
  1313. X    case CAMG:
  1314. X    case CRNG:
  1315. X    case CCRT:
  1316. X#endif PARANOID
  1317. X        bit_bucket(file, chunk.iff_length);
  1318. X        break;
  1319. X    }
  1320. X    read_in += EVEN(chunk.iff_length) + sizeof (chunk);
  1321. X    }
  1322. X#ifdef PARANOID
  1323. X    printf("no BODY in ILBM\n");
  1324. X#endif PARANOID
  1325. X    return NULL;
  1326. X}
  1327. X
  1328. X
  1329. X
  1330. XSTATIC struct ILBM_info *
  1331. Xwin_read_body(file, info, length, window)
  1332. XFILE           *file;
  1333. Xregister struct ILBM_info *info;
  1334. Xlong        length;
  1335. Xstruct Window  *window;
  1336. X{
  1337. X    struct ILBM_header *header;
  1338. X    struct BitMap  *bm;
  1339. X    int         i,
  1340. X            j;
  1341. X    int         rlength;
  1342. X    int         plane_offset;
  1343. X    ULONG        YSize,
  1344. X            DestX,
  1345. X            DestY;
  1346. X
  1347. X#ifdef DEBUG
  1348. X    printf("win_read_body( %lx %lx %ld)\n", file, info, length);
  1349. X#endif DEBUG
  1350. X
  1351. X#ifdef PARANOID
  1352. X    /*
  1353. X     * When paranoid do a little error checking first ... fail fast!
  1354. X     */
  1355. X    if (info->header.nPlanes > 8) {
  1356. X    printf("Whoa, woe  Dale only speaks 8 planes boy, not %d\n",
  1357. X           info->header.nPlanes);
  1358. X    return NULL;
  1359. X    }
  1360. X#endif PARANOID
  1361. X
  1362. X    /*
  1363. X     * Ok a little more error checking
  1364. X     */
  1365. X    if (info->header.compression != 0 && info->header.compression != 1) {
  1366. X#ifdef PARANOID
  1367. X    printf("unrecognized compression type %d\n", info->header.compression);
  1368. X#endif PARANOID
  1369. X    return NULL;
  1370. X    }
  1371. X    /*
  1372. X     * Set up the bitmap part that doesn't involve memory allocation first
  1373. X     * - hey this part does get done, and let's be optimistic...
  1374. X     */
  1375. X    info->bitmap.BytesPerRow = line_bytes(info->header.w);
  1376. X    info->bitmap.Rows = info->header.h;
  1377. X    info->bitmap.Depth = info->header.nPlanes;
  1378. X    info->bitmap.Flags = info->bitmap.pad = 0;
  1379. X
  1380. X    rlength = info->bitmap.Rows * info->bitmap.BytesPerRow;
  1381. X
  1382. X    for (i = 0; i < info->header.nPlanes; i++) {
  1383. X    if ((info->bitmap.Planes[i] = ralloc(rlength)) == NULL) {
  1384. X#ifdef PARANOID
  1385. X        printf("couldn't alloc plane %d in win_read_body\n", i);
  1386. X#endif PARANOID
  1387. X        free_planes(&info->bitmap);
  1388. X        return NULL;
  1389. X    }
  1390. X    }
  1391. X
  1392. X    plane_offset = 0;
  1393. X    YSize = (MAXPLANESIZE / info->bitmap.BytesPerRow);
  1394. X    if (window->Flags & GIMMEZEROZERO) {
  1395. X    DestX = 0;
  1396. X    DestY = 0;
  1397. X    } else {
  1398. X    DestX = window->BorderLeft;
  1399. X    DestY = window->BorderTop;
  1400. X    }
  1401. X
  1402. X    for (i = 0; i < info->bitmap.Rows; i++) {
  1403. X    /*
  1404. X     * This test should be in the inner loop for shortest code, in the
  1405. X     * outer loop for greatest speed, so sue me I compromised
  1406. X     */
  1407. X    if (info->header.compression == 0) {
  1408. X        for (j = 0; j < info->bitmap.Depth; j++) {
  1409. X        if (fread(info->bitmap.Planes[j] + plane_offset,
  1410. X              info->bitmap.BytesPerRow, 1, file) != 1) {
  1411. X#ifdef PARANOID
  1412. X            iff_truncated(6);
  1413. X#endif PARANOID
  1414. X            free_planes(&info->bitmap);
  1415. X            return NULL;
  1416. X        }
  1417. X        }
  1418. X    } else {
  1419. X        register char  *dest,
  1420. X                value;
  1421. X        register int    so_far,
  1422. X                count;    /* How much have unpacked so far */
  1423. X
  1424. X        for (j = 0; j < info->bitmap.Depth; j++) {
  1425. X        so_far = info->bitmap.BytesPerRow;
  1426. X        dest = (char *) info->bitmap.Planes[j] + plane_offset;
  1427. X        while (so_far > 0) {
  1428. X            if ((value = getc(file)) == 128) {
  1429. X#ifdef DEBUG
  1430. X            printf("NOP\n");
  1431. X#endif DEBUG
  1432. X            } else if (value > 0) {
  1433. X            count = (int) value + 1;
  1434. X            so_far -= count;
  1435. X            if (fread(dest, count, 1, file) != 1) {
  1436. X#ifdef PARANOID
  1437. X                iff_truncated(7);
  1438. X#endif PARANOID
  1439. X                free_planes(&info->bitmap);
  1440. X                return NULL;
  1441. X            }
  1442. X            dest += count;
  1443. X            } else {
  1444. X            count = (int) -value + 1;
  1445. X            so_far -= count;
  1446. X            value = getc(file);
  1447. X            while (--count >= 0)    /* This is fastest loop on
  1448. X                         * the 68000 */
  1449. X                *dest++ = value;
  1450. X            }
  1451. X        }
  1452. X        if (so_far != 0) {
  1453. X#ifdef PARANOID
  1454. X            printf("compression quite screwed up, aborting %d\n", so_far);
  1455. X#endif PARANOID
  1456. X            free_planes(&info->bitmap);
  1457. X            return NULL;
  1458. X        }
  1459. X        }
  1460. X    }
  1461. X    plane_offset += info->bitmap.BytesPerRow;
  1462. X
  1463. X    if (plane_offset > MAXPLANESIZE - info->bitmap.BytesPerRow) {
  1464. X        BltBitMapRastPort(&info->bitmap, 0L, 0L,
  1465. X                  window->RPort, DestX, DestY,
  1466. X                  info->bitmap.BytesPerRow * 8L, YSize,
  1467. X                  COPY_MINTERM);
  1468. X        plane_offset = 0;
  1469. X        DestY += YSize;
  1470. X    }
  1471. X    }
  1472. X
  1473. X    if (plane_offset) {
  1474. X    BltBitMapRastPort(&info->bitmap, 0L, 0L,
  1475. X              window->RPort, DestX, DestY,
  1476. X              info->bitmap.BytesPerRow * 8L,
  1477. X              (long) plane_offset / info->bitmap.BytesPerRow,
  1478. X              COPY_MINTERM);
  1479. X    }
  1480. X    if (length & 1) {
  1481. X    /*
  1482. X     * Skip padding byte
  1483. X     */
  1484. X    getc(file);
  1485. X    }
  1486. X    free_planes(&info->bitmap);
  1487. X    return info;
  1488. X}
  1489. X
  1490. X
  1491. Xvoid
  1492. Xfree_planes(bmap)
  1493. Xregister struct BitMap *bmap;
  1494. X{
  1495. X    PLANEPTR        plane;
  1496. X    long        length;
  1497. X    short        i;
  1498. X
  1499. X    length = bmap->BytesPerRow * bmap->Rows;
  1500. X
  1501. X    for (i = bmap->Depth; --i >= 0;) {
  1502. X    if ((plane = bmap->Planes[i]) != NULL) {
  1503. X        rfree(plane, length);
  1504. X        bmap->Planes[i] = NULL;
  1505. X    }
  1506. X    }
  1507. X}
  1508. X
  1509. X
  1510. X
  1511. X
  1512. X
  1513. X
  1514. X#undef DEBUG
  1515. X/* #define DEBUG/* */
  1516. X#undef PARANOID
  1517. X
  1518. X/*----------------------------------------------------------------------*
  1519. X * jpacker.c Convert data to "cmpByteRun1" run compression.
  1520. X *
  1521. X * pack_row() is an adaptation of PackRow()
  1522. X * by Jerry Morrison and Steve Shaw, Electronic Arts,
  1523. X * modified and tweaked by Jim Kent, Dancing Flame 05/02/86
  1524. X *
  1525. X *  control bytes:
  1526. X *   [0..127]    : followed by n+1 bytes of data.
  1527. X *   [-1..-127] : followed by byte to be repeated(-n)+1 times.
  1528. X *   -128    : NOOP.
  1529. X *
  1530. X *
  1531. X * write_iff() is the only function you can access in this module.
  1532. X *----------------------------------------------------------------------*/
  1533. X
  1534. X/*-
  1535. X#include <exec/types.h>
  1536. X#include <graphics/gfx.h>
  1537. X#include <stdio.h>
  1538. X#include "jiff.h"
  1539. X*/
  1540. X
  1541. X#define DUMP    0
  1542. X#define RUN 1
  1543. X
  1544. X#define MINRUN 3
  1545. X#define MAXRUN 128
  1546. X#define MAXDAT 128
  1547. X
  1548. X/*
  1549. X * pack_row - pass source line pointer, length of line, and file. Returns
  1550. X * # of bytes after compression.  Returns 0 on write error. Pass file =
  1551. X * NULL to just find out length, otherwise will write compressed row to
  1552. X * file.
  1553. X */
  1554. X
  1555. XSTATIC unsigned int
  1556. Xpack_row(file, source, size)
  1557. XFILE           *file;
  1558. Xchar           *source;
  1559. Xint        size;
  1560. X{
  1561. X    char        c,
  1562. X            lastc = '\0';
  1563. X    short        mode = DUMP;
  1564. X    short        nbuf = 0;    /* Number of chars in buffer */
  1565. X    short        rstart = 0; /* Buffer index current run starts */
  1566. X    unsigned short  putsize;
  1567. X
  1568. X#if OLD
  1569. X    char        buf[MAXDAT * 3 / 2];    /* I think MAXDAT+1 would
  1570. X                         * suffice */
  1571. X
  1572. X#else
  1573. X    /*
  1574. X     * And I think that buf can be changed into a pointer to the source
  1575. X     * line, to the beginning of a dump. Saves stack space and copying.
  1576. X     */
  1577. X    char       *buf;
  1578. X
  1579. X#endif
  1580. X
  1581. X    putsize = 0;
  1582. X#if OLD
  1583. X    buf[0] = lastc = *source++; /* So have valid lastc */
  1584. X#else
  1585. X    buf = source;
  1586. X    lastc = *source++;        /* So have valid lastc */
  1587. X#endif
  1588. X    nbuf = 1;
  1589. X    size--;            /* Since one byte eaten */
  1590. X
  1591. X
  1592. X    for (; size; --size) {
  1593. X#if OLD
  1594. X    buf[nbuf++] = c = *source++;
  1595. X#else
  1596. X    nbuf++;
  1597. X    c = *source++;
  1598. X#endif
  1599. X    switch (mode) {
  1600. X    case DUMP:
  1601. X        /*
  1602. X         * If the buffer is full, write the length byte, then the data
  1603. X         */
  1604. X        if (nbuf > MAXDAT) {
  1605. X        if (file != NULL) {
  1606. X            if (putc(nbuf - 2, file) == EOF)
  1607. X            return 0;
  1608. X            if (fwrite(buf, nbuf - 1, 1, file) != 1)
  1609. X            return 0;
  1610. X        }
  1611. X        putsize += nbuf;
  1612. X#if OLD
  1613. X        buf[0] = c;
  1614. X#else
  1615. X        buf = source - 1;    /* Undo the previous source++ */
  1616. X#endif
  1617. X        nbuf = 1;
  1618. X        rstart = 0;
  1619. X        break;
  1620. X        }
  1621. X        if (c == lastc) {
  1622. X        if (nbuf - rstart >= MINRUN) {
  1623. X            if (rstart > 0) {
  1624. X            if (file != NULL) {
  1625. X                if (putc(rstart - 1, file) == EOF)
  1626. X                return 0;
  1627. X                if (fwrite(buf, rstart, 1, file) != 1)
  1628. X                return 0;
  1629. X            }
  1630. X            putsize += rstart + 1;
  1631. X            }
  1632. X            mode = RUN;
  1633. X        } else if (rstart == 0)
  1634. X            mode = RUN;
  1635. X        /*
  1636. X         * No dump in progress, so can't lose by making these 2 a
  1637. X         * run.
  1638. X         */
  1639. X        } else
  1640. X        rstart = nbuf - 1;    /* First of run */
  1641. X        break;
  1642. X
  1643. X    case RUN:
  1644. X        if ((c != lastc) || (nbuf - rstart > MAXRUN)) {
  1645. X        /*
  1646. X         * Output run
  1647. X         */
  1648. X        if (file != NULL) {
  1649. X            if (putc(-(nbuf - rstart - 2), file) == EOF)
  1650. X            return 0;
  1651. X            if (putc(lastc, file) == EOF)
  1652. X            return 0;
  1653. X        }
  1654. X        putsize += 2;
  1655. X#if OLD
  1656. X        buf[0] = c;
  1657. X#else
  1658. X        buf = source - 1;    /* Undo the previous source++ */
  1659. X#endif
  1660. X        nbuf = 1;
  1661. X        rstart = 0;
  1662. X        mode = DUMP;
  1663. X        }
  1664. X        break;
  1665. X    }
  1666. X
  1667. X    lastc = c;
  1668. X    }
  1669. X
  1670. X    switch (mode) {
  1671. X    case DUMP:
  1672. X    if (file != NULL) {
  1673. X        if (putc(nbuf - 1, file) == EOF)
  1674. X        return 0;
  1675. X        if (fwrite(buf, nbuf, 1, file) != 1)
  1676. X        return 0;
  1677. X    }
  1678. X    putsize += nbuf + 1;
  1679. X    break;
  1680. X    case RUN:
  1681. X    if (file != NULL) {
  1682. X        if (putc(-(nbuf - rstart - 1), file) == EOF)
  1683. X        return 0;
  1684. X        if (putc(lastc, file) == EOF)
  1685. X        return 0;
  1686. X    }
  1687. X    putsize += 2;
  1688. X    break;
  1689. X    }
  1690. X    return putsize;
  1691. X}
  1692. X
  1693. X/*
  1694. X * write_row - pass source line pointer, length of line, and file. Returns
  1695. X * # of bytes after not compressing.  Returns 0 on write error. Pass file
  1696. X * = NULL to just find out length, otherwise will write non-compressed row
  1697. X * to file.
  1698. X */
  1699. X
  1700. XSTATIC unsigned int
  1701. Xwrite_row(file, source, size)
  1702. XFILE           *file;
  1703. Xchar           *source;
  1704. Xint        size;
  1705. X{
  1706. X    if (file) {
  1707. X    if (fwrite(source, size, 1, file) != 1)
  1708. X        return 0;
  1709. X    }
  1710. X    return size;
  1711. X}
  1712. X
  1713. X
  1714. XSTATIC unsigned long
  1715. Xpack_window(file, window, writer)
  1716. XFILE           *file;
  1717. Xregister struct Window *window;
  1718. Xregister unsigned int (*writer) ();
  1719. X
  1720. X{
  1721. X    unsigned short  i,
  1722. X            j;
  1723. X    unsigned        row_length;
  1724. X    unsigned long   compressed_length;
  1725. X    unsigned        plane_offset;
  1726. X    int         BytesPerRow;
  1727. X    int         YSize;
  1728. X    ULONG        SrcX,
  1729. X            SrcY;
  1730. X    struct RastPort Rp;
  1731. X    struct BitMap   Bitmap;
  1732. X
  1733. X#ifdef DEBUG
  1734. X    printf("pack_window( %lx %lx)\n", file, window);
  1735. X#endif DEBUG
  1736. X
  1737. X    compressed_length = 0;
  1738. X    plane_offset = 0;
  1739. X
  1740. X    BytesPerRow = line_bytes(window->GZZWidth);
  1741. X    Bitmap.Depth = window->WScreen->BitMap.Depth;
  1742. X    if (window->Flags & GIMMEZEROZERO) {
  1743. X    SrcX = 0;
  1744. X    SrcY = 0;
  1745. X    } else {
  1746. X    SrcX = window->BorderLeft;
  1747. X    SrcY = window->BorderTop;
  1748. X    }
  1749. X    YSize = MAXPLANESIZE / BytesPerRow;
  1750. X    InitBitMap(&Bitmap, (ULONG) Bitmap.Depth,
  1751. X           (ULONG) (8 * BytesPerRow), (ULONG) YSize);
  1752. X
  1753. X    /*
  1754. X     * Make sure the Planes are all NULL so can free up memory easily on
  1755. X     * error abort
  1756. X     */
  1757. X    for (i = 0; i < 8; i++)
  1758. X    Bitmap.Planes[i] = NULL;
  1759. X
  1760. X    for (i = 0; i < Bitmap.Depth; i++) {
  1761. X    if ((Bitmap.Planes[i] = ralloc(MAXPLANESIZE)) == NULL) {
  1762. X#ifdef DEBUG
  1763. X        printf("couldn't alloc plane %d in pack_window\n", i);
  1764. X        printf("pack_window: aborting; free_planes\n");
  1765. X#endif
  1766. X        free_planes(&Bitmap);
  1767. X        return 0;
  1768. X    }
  1769. X    }
  1770. X    InitRastPort(&Rp);
  1771. X    Rp.BitMap = &Bitmap;
  1772. X#ifdef DEBUG
  1773. X    printf("pack_window BytesPerRow=%ld Depth=%ld\n", (long) BytesPerRow,
  1774. X       (long) Bitmap.Depth);
  1775. X#endif
  1776. X
  1777. X    for (i = 0; i < window->GZZHeight; i++) {
  1778. X    if (plane_offset == 0) {
  1779. X#ifdef DEBUG
  1780. X        printf("pack_window ClipBlit SrcX=%ld SrcY=%ld YSize=%ld\n",
  1781. X           SrcX, SrcY, (ULONG) YSize);
  1782. X#endif
  1783. X#define DestX    0L
  1784. X#define DestY    0L
  1785. X        ClipBlit(window->RPort, SrcX, SrcY,
  1786. X             &Rp, DestX, DestY,
  1787. X             (ULONG) window->GZZWidth, (ULONG) YSize,
  1788. X             COPY_MINTERM);
  1789. X#undef DestX
  1790. X#undef DestY
  1791. X        SrcY += YSize;
  1792. X    }
  1793. X    for (j = 0; j < Bitmap.Depth; j++) {
  1794. X        if ((row_length = (*writer) (file, Bitmap.Planes[j] + plane_offset,
  1795. X                     BytesPerRow)) == 0) {
  1796. X#ifdef DEBUG
  1797. X        printf("error packing row %d plane %d\n", i, j);
  1798. X        printf("pack_window: aborting; free_planes\n");
  1799. X#endif
  1800. X        free_planes(&Bitmap);
  1801. X        return 0;
  1802. X        }
  1803. X        compressed_length += row_length;
  1804. X    }
  1805. X
  1806. X    plane_offset += BytesPerRow;
  1807. X    if (plane_offset > MAXPLANESIZE - BytesPerRow)
  1808. X        plane_offset = 0;
  1809. X    }
  1810. X
  1811. X#ifdef DEBUG
  1812. X    printf("pack_window: free_planes\n");
  1813. X#endif
  1814. X    free_planes(&Bitmap);
  1815. X
  1816. X    if (compressed_length & 1) {/* Check to see odd length */
  1817. X    if (file != NULL) {
  1818. X        if (putc(0, file) == EOF) {
  1819. X        return 0;
  1820. X        }
  1821. X    }
  1822. X    /*
  1823. X     * compressed_length++; Deleted!!! Padding should NOT be included
  1824. X     * in the chunk size !!!
  1825. X     */
  1826. X    }
  1827. X    return compressed_length;
  1828. X}
  1829. X
  1830. Xint
  1831. Xwrite_iff(name, colors, window, xoff, yoff, compressed, MandSize, MandPointer)
  1832. Xchar           *name;
  1833. Xunsigned char  *colors;
  1834. Xregister struct Window *window;
  1835. Xshort        xoff,
  1836. X        yoff;
  1837. Xshort        compressed;
  1838. Xint        MandSize;
  1839. XAPTR        MandPointer;
  1840. X{
  1841. X    FILE       *file;
  1842. X    struct form_chunk chunk;
  1843. X    struct iff_chunk ichunk;
  1844. X    struct BitMapHeader header;
  1845. X    long        bits_size;
  1846. X    short        i;
  1847. X    int         width = 0;
  1848. X    int         Depth;
  1849. X    int         BytesPerRow;
  1850. X
  1851. X#ifdef DEBUG
  1852. X    printf("write_iff\n");
  1853. X#endif
  1854. X
  1855. X    if ((file = fopen(name, "w")) == 0) {
  1856. X#ifdef PARANOID
  1857. X    printf("couldn't fopen %s to write\n", name);
  1858. X#endif PARANOID
  1859. X    goto abort;
  1860. X    }
  1861. X    /*
  1862. X     * Say its a FORM ILBM
  1863. X     */
  1864. X    chunk.fc_type.b4_type = FORM;
  1865. X    chunk.fc_subtype.b4_type = ILBM;
  1866. X#ifdef MANDEL
  1867. X    chunk.fc_length = 4 + 3 * sizeof (struct iff_chunk) + MAXCOL * 3 +
  1868. X    sizeof (struct BitMapHeader) + sizeof (struct CommodoreAmiga) + MandSize;
  1869. X#else
  1870. X    chunk.fc_length = 4 + 3 * sizeof (struct iff_chunk) + MAXCOL * 3 +
  1871. X    sizeof (struct BitMapHeader) + sizeof (struct CommodoreAmiga);
  1872. X#endif MANDEL
  1873. X    if (window) {
  1874. X    width = window->GZZWidth;
  1875. X    BytesPerRow = line_bytes(width);
  1876. X    Depth = window->WScreen->BitMap.Depth;
  1877. X    if (compressed) {
  1878. X#ifdef DEBUG
  1879. X        printf("write_iff: call pack_window for sizing\n");
  1880. X#endif
  1881. X        if ((bits_size = pack_window(NULL, window, pack_row)) == 0)
  1882. X        goto abort;
  1883. X    } else {
  1884. X        bits_size = BytesPerRow * window->GZZHeight * Depth;
  1885. X    }
  1886. X    chunk.fc_length += bits_size;
  1887. X    if (bits_size & 1)
  1888. X        chunk.fc_length++;
  1889. X    }
  1890. X    if (fwrite(&chunk, sizeof (chunk), 1, file) != 1)
  1891. X    goto abort;
  1892. X
  1893. X    /*
  1894. X     * Here comes a BitMapHeader
  1895. X     */
  1896. X    {
  1897. X    struct iff_chunk ichunk;
  1898. X
  1899. X    ichunk.iff_type.b4_type = BMHD;
  1900. X    ichunk.iff_length = sizeof (header);
  1901. X    if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1)
  1902. X        goto abort;
  1903. X    }
  1904. X
  1905. X    /*
  1906. X     * Initialize the BitMapHeader to normal values
  1907. X     */
  1908. X    header.masking = 0;
  1909. X    header.pad1 = 0;
  1910. X    header.transparentColor = 0;
  1911. X    if (compressed)
  1912. X    header.compression = 1;
  1913. X    else
  1914. X    header.compression = 0;
  1915. X    header.pageWidth = width;
  1916. X    header.pageHeight = window ? window->GZZHeight : YMAX;
  1917. X    header.xAspect = width > LOXMAX ? XASPECT : XASPECT * 2;
  1918. X    header.yAspect = YASPECT;
  1919. X    /*
  1920. X     * If it's not just a color map give the dimensions of rasters
  1921. X     */
  1922. X    if (window) {
  1923. X    header.w = width;
  1924. X    header.h = window->GZZHeight;
  1925. X    header.nPlanes = Depth;
  1926. X    header.x = xoff;
  1927. X    header.y = yoff;
  1928. X    }
  1929. X    if (fwrite(&header, sizeof (header), 1, file) != 1)
  1930. X    goto abort;
  1931. X
  1932. X    /*
  1933. X     * Squirt out the color map
  1934. X     */
  1935. X    {
  1936. X    struct iff_chunk ichunk;
  1937. X
  1938. X    ichunk.iff_type.b4_type = CMAP;
  1939. X    ichunk.iff_length = MAXCOL * 3;
  1940. X    if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1)
  1941. X        goto abort;
  1942. X    if (fwrite(colors, (int) 3 * MAXCOL, 1, file) != 1)
  1943. X        goto abort;
  1944. X    }
  1945. X
  1946. X    /*
  1947. X     * Write a CAMG chunk with ViewPort modes
  1948. X     */
  1949. X    {
  1950. X    struct CommodoreAmiga camg;
  1951. X
  1952. X    camg.camg_iffc.iff_type.b4_type = CAMG;
  1953. X    camg.camg_iffc.iff_length = sizeof (camg) - sizeof (camg.camg_iffc);
  1954. X    camg.camg_data = window->WScreen->ViewPort.Modes;
  1955. X    if (fwrite(&camg, sizeof (camg), 1, file) != 1)
  1956. X        goto abort;
  1957. X    }
  1958. X
  1959. X#ifdef MANDEL
  1960. X    /*
  1961. X     * We want to write our own private MAND chunk
  1962. X     */
  1963. X    if (MandSize) {
  1964. X    if (fwrite(MandPointer, MandSize, 1, file) != 1)
  1965. X        goto abort;
  1966. X    }
  1967. X#endif MANDEL
  1968. X
  1969. X    /*
  1970. X     * If they be bits then squirt out the bits
  1971. X     */
  1972. X    if (window) {
  1973. X    struct iff_chunk ichunk;
  1974. X
  1975. X    ichunk.iff_type.b4_type = BODY;
  1976. X    ichunk.iff_length = bits_size;
  1977. X    if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1)
  1978. X        goto abort;
  1979. X#ifdef DEBUG
  1980. X    printf("write_iff: call pack_window for real\n");
  1981. X#endif
  1982. X    if (compressed) {
  1983. X        if (pack_window(file, window, pack_row) == 0)
  1984. X        goto abort;
  1985. X    } else {
  1986. X        if (pack_window(file, window, write_row) == 0)
  1987. X        goto abort;
  1988. X    }
  1989. X    }
  1990. X    fclose(file);
  1991. X
  1992. X    return 1;
  1993. Xabort:
  1994. X#ifdef DEBUG
  1995. X    printf("write_iff: aborting !!!\n");
  1996. X#endif
  1997. X    fclose(file);
  1998. X    return 0;
  1999. X}
  2000. X
  2001. X
  2002. X/*
  2003. X * put_ea_cmap given an ea-type color map:
  2004. X *
  2005. X * an array of unsigned chars of form ea_cmap[] = {r, g, b, r, g, b...}
  2006. X *
  2007. X * turn it into an amiga-type color map:
  2008. X *
  2009. X * an array of unsigned short of form amiga_cmap = {0xrgb, 0xrgb, ...}
  2010. X *
  2011. X * and then tell Dale this is the colors we want for our viewport
  2012. X */
  2013. X
  2014. Xvoid
  2015. Xput_ea_cmap(ea_cmap, colors, Screen)
  2016. Xunsigned char  *ea_cmap;
  2017. Xint        colors;
  2018. Xstruct Screen  *Screen;
  2019. X{
  2020. X    unsigned short  amy_cmap[MAXCOL];
  2021. X    register int    i;
  2022. X    register short  color;
  2023. X
  2024. X    if (colors > MAXCOL)        /* Color clipping */
  2025. X    colors = MAXCOL;
  2026. X    for (i = 0; i < colors; i++) {
  2027. X    color = (*ea_cmap++ & 0xF0) << 4;
  2028. X    color |= *ea_cmap++ & 0xF0;
  2029. X    color |= (*ea_cmap++ & 0xF0) >> 4;
  2030. X    amy_cmap[i] = color;
  2031. X    }
  2032. X    LoadRGB4(&Screen->ViewPort, amy_cmap, (long) colors);
  2033. X}
  2034. X
  2035. Xvoid
  2036. Xget_ea_cmap(ea_cmap, colors, Screen)
  2037. Xunsigned char  *ea_cmap;
  2038. Xint        colors;
  2039. Xstruct Screen  *Screen;
  2040. X{
  2041. X    register long   i;
  2042. X    register unsigned short rgb;
  2043. X
  2044. X    if (colors > MAXCOL)        /* Color clipping */
  2045. X    colors = MAXCOL;
  2046. X    for (i = 0; i < colors; i++) {
  2047. X    rgb = GetRGB4(Screen->ViewPort.ColorMap, i);
  2048. X    *ea_cmap++ = (rgb & 0xF00) >> 4;
  2049. X    *ea_cmap++ = (rgb & 0x0F0);
  2050. X    *ea_cmap++ = (rgb & 0x00F) << 4;
  2051. X    }
  2052. X}
  2053. SHAR_EOF
  2054. echo "End of archive 2 (of 4)"
  2055. # if you want to concatenate archives, remove anything after this line
  2056. exit
  2057.